package com.casstime.ec.cloud.discount.services;

import java.math.BigDecimal;
import java.text.MessageFormat;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.casstime.commons.utils.IncrementIdCreator;
import com.casstime.ec.cloud.discount.dao.amount.AmountPromotionConfigAmountMapper;
import com.casstime.ec.cloud.discount.dao.amount.AmountPromotionConfigAreaMapper;
import com.casstime.ec.cloud.discount.dao.amount.AmountPromotionConfigBrandMapper;
import com.casstime.ec.cloud.discount.dao.amount.AmountPromotionConfigCategoryMapper;
import com.casstime.ec.cloud.discount.dao.amount.AmountPromotionConfigMapper;
import com.casstime.ec.cloud.discount.dao.amount.AmountPromotionMapper;
import com.casstime.ec.cloud.discount.dao.amount.AmountPromotionUpdateRecordMapper;
import com.casstime.ec.cloud.discount.model.AmountOrderInfo;
import com.casstime.ec.cloud.user.spi.models.User;
import com.casstime.ec.cloud.values.amountPromotion.AmountPromotion;
import com.casstime.ec.cloud.values.amountPromotion.AmountPromotionConfig;
import com.casstime.ec.cloud.values.amountPromotion.AmountPromotionConfigAmount;
import com.casstime.ec.cloud.values.amountPromotion.AmountPromotionConfigArea;
import com.casstime.ec.cloud.values.amountPromotion.AmountPromotionConfigBrand;
import com.casstime.ec.cloud.values.amountPromotion.AmountPromotionConfigCategory;
import com.casstime.ec.cloud.values.amountPromotion.AmountPromotionRequest;
import com.casstime.ec.cloud.values.amountPromotion.AmountPromotionUpdateRecord;
import com.casstime.ec.cloud.values.amountPromotion.enums.DiscountConfigValueEnum;
import com.github.pagehelper.Page;
import com.github.pagehelper.PageHelper;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;

import net.sourceforge.pinyin4j.PinyinHelper;
import net.sourceforge.pinyin4j.format.HanyuPinyinCaseType;
import net.sourceforge.pinyin4j.format.HanyuPinyinOutputFormat;
import net.sourceforge.pinyin4j.format.HanyuPinyinToneType;
import net.sourceforge.pinyin4j.format.exception.BadHanyuPinyinOutputFormatCombination;

/**
 * ClassName: DiscountServiceImpl 
 * Function: (金额促销实现类)
 * Reason: ADD REASON(可选).
 *  
 * @author wu.chen 
 * 2018年2月26日 上午11:02:13
 * @version   
 * @since JDK 1.8
 */
@Service
public class DiscountDAOService {
	
	private Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	private AmountPromotionMapper amountPromotionMapper;
	
	@Autowired
	private AmountPromotionConfigAmountMapper amountPromotionConfigAmountMapper;
	
	@Autowired
	private AmountPromotionConfigAreaMapper amountPromotionConfigAreaMapper;
	
	@Autowired
	private AmountPromotionConfigCategoryMapper amountPromotionConfigCategoryMapper;
	
	@Autowired
	private AmountPromotionConfigBrandMapper amountPromotionConfigBrandMapper;
	
	@Autowired
	private AmountPromotionConfigMapper amountPromotionConfigMapper;
	
	@Autowired
	private AmountPromotionUpdateRecordMapper updateRecordMapper;


	public int addAmountPromotion(AmountPromotion amountPromotion, User user) {
		IncrementIdCreator idCreator = new IncrementIdCreator();
		Date now = new Date();
		
		//生成首字母加时间的Id
		SimpleDateFormat simpleformat = new SimpleDateFormat("yyyyMMddHHmmss");
		HanyuPinyinOutputFormat pinyinFormat = new HanyuPinyinOutputFormat();
		pinyinFormat.setToneType(HanyuPinyinToneType.WITH_TONE_NUMBER);
		pinyinFormat.setCaseType(HanyuPinyinCaseType.UPPERCASE);
		char[] arr = amountPromotion.getPromotionName().toCharArray(); 
		StringBuffer promotionCode = new StringBuffer();
		for (int i = 0; i < arr.length; i++) {
	         if (arr[i] > 128) { 
                 try {   
                     String[] temp = PinyinHelper.toHanyuPinyinStringArray(arr[i], pinyinFormat);   
                     if (temp != null) {   
                    	 promotionCode.append(temp[0].charAt(0));   
                     }   
                 } catch (BadHanyuPinyinOutputFormatCombination e) {   
                         logger.error("拼音转化失败{}", arr[i], e);
                 }
	         } else {   
	        	 promotionCode.append(arr[i]);   
	         }   
		}
		promotionCode.append(simpleformat.format(now));
		
		amountPromotion.setId(idCreator.getNextIncrementId());
		amountPromotion.setPromotionCode(promotionCode.toString());
		amountPromotion.setLastUpdatedBy(user.getUserLoginId());
		amountPromotion.setLastUpdatedStamp(now);
		amountPromotion.setExcessBudget(BigDecimal.ZERO);
		amountPromotion.setPromotionStatus("Y");
		List<AmountPromotion> promotions = Lists.newArrayList();
		promotions.add(amountPromotion);
		int ret = amountPromotionMapper.insertOrUpdateAmountPromotion(amountPromotion);
		if (ret > 0) {
			insertPromotionConfigs(amountPromotion, idCreator);
			List<AmountPromotionUpdateRecord> records = Lists.newArrayList();
			AmountPromotionUpdateRecord record = new AmountPromotionUpdateRecord();
			record.setId(idCreator.getNextIncrementId());
			record.setPromotionId(amountPromotion.getId());
			record.setUserLoginId(user.getUserLoginId());
			record.setUserLoginName(user.getUserName());
			record.setCreatedStamp(now);
			record.setDescription(MessageFormat.format("新增 满减优惠活动： {0}", amountPromotion.getPromotionName()));
			records.add(record);
			updateRecordMapper.insertAmountPromotionRecords(records);
			return 1;
		} else {
			return 0;
		}
	}
	
	public int updateAmountPromotion(AmountPromotion amountPromotion, User user) {
		IncrementIdCreator idCreator = new IncrementIdCreator();
		Date now = new Date();
		amountPromotion.setLastUpdatedBy(user.getUserLoginId());
		AmountPromotion oldPromotion = findAmountPromotion(amountPromotion.getId());
		int ret = amountPromotionMapper.insertOrUpdateAmountPromotion(amountPromotion);
		if (ret > 0) {
			amountPromotionMapper.deleteAmountPromotionById(amountPromotion.getId());
			insertPromotionConfigs(amountPromotion, idCreator);
			List<AmountPromotionUpdateRecord> records = Lists.newArrayList();
			AmountPromotionUpdateRecord record = createUpdateRecord(oldPromotion, amountPromotion, idCreator, user, now);
			if (record != null) {
				records.add(record);
				updateRecordMapper.insertAmountPromotionRecords(records);
			}
			return 1;
		} else {
			return 0;
		}
	}

	public AmountPromotion findAmountPromotion(String promotionId) {
		AmountPromotion promotion = amountPromotionMapper.findAmountPromotionById(promotionId);
		if (promotion == null) {
			return null;
		}
		List<String> promotionIds = Lists.newArrayList();
		promotionIds.add(promotion.getId());
		List<AmountPromotionConfigAmount> amounts = this.findConfigAmountByPromotionIds(promotionIds);
		promotion.setPromotionAmounts(amounts);
		promotion.setPromotionConfigs(listPromotionConfigs(promotionIds));
		return promotion;
	}
	
	public int addAmountPromotionAmount(String promotionId, BigDecimal amount) {
		return amountPromotionMapper.addAmountPromotionAmount(promotionId, amount);
	}
	
	public List<AmountPromotion> listAvailableAmountPromotions(List<String> productStoreIds, String platform) {
		List<AmountPromotion> promotions = amountPromotionMapper.listAvailableAmountPromotions(productStoreIds, platform);
		if (CollectionUtils.isEmpty(promotions)) {
			return Lists.newArrayList();
		}
		Iterator<AmountPromotion> tempIt = promotions.iterator();
		while (tempIt.hasNext()) {
			AmountPromotion temp = tempIt.next();
			if (StringUtils.isNotBlank(temp.getPromotionBudget())
					&& temp.getExcessBudget().compareTo(new BigDecimal(temp.getPromotionBudget())) >= 0) {
				tempIt.remove();
			}
		}
		if (CollectionUtils.isEmpty(promotions)) {
			return Lists.newArrayList();
		}
		List<String> promotionIds = promotions.stream().map(AmountPromotion::getId).collect(Collectors.toList());
		List<AmountPromotionConfigAmount> amounts = this.findConfigAmountByPromotionIds(promotionIds);
		List<AmountPromotionConfig> configs = listPromotionConfigs(promotionIds);
		for (AmountPromotion promotion : promotions) {
			for (AmountPromotionConfigAmount amount : amounts) {
				if (amount.getPromotionId().equals(promotion.getId())) {
					if (promotion.getPromotionAmounts() != null) {
						promotion.getPromotionAmounts().add(amount);
					} else {
						List<AmountPromotionConfigAmount> temps = Lists.newArrayList();
						temps.add(amount);
						promotion.setPromotionAmounts(temps);
					}
				}
			}
			for (AmountPromotionConfig config : configs) {
				if (config.getPromotionId().equals(promotion.getId())) {
					if (promotion.getPromotionConfigs() != null) {
						promotion.getPromotionConfigs().add(config);
					} else {
						List<AmountPromotionConfig> temps = Lists.newArrayList();
						temps.add(config);
						promotion.setPromotionConfigs(temps);
					}
				}
			}
		}
		
		Iterator<AmountPromotion> budgetIt = promotions.iterator();
		while (budgetIt.hasNext()) {
			AmountPromotion temp = budgetIt.next();
			if (StringUtils.isNotBlank(temp.getPromotionBudget())) {
				BigDecimal dis = new BigDecimal(temp.getPromotionBudget()).subtract(temp.getExcessBudget());
				Iterator<AmountPromotionConfigAmount> configIt = temp.getPromotionAmounts().iterator();
				while (configIt.hasNext()) {
					AmountPromotionConfigAmount tempConfig = configIt.next();
					BigDecimal cut = new BigDecimal(tempConfig.getOffAmount());
					if (dis.compareTo(cut) < 0) {
						configIt.remove();
					}
				}
				if (CollectionUtils.isEmpty(temp.getPromotionAmounts())) {
					budgetIt.remove();
					break;
				}
			}
		}
		return promotions;
	}
	
	public Page<AmountPromotion> listAmountPromotionStoreId(String productStoreId, Integer pageSize, Integer pageNum,
			AmountPromotionRequest request) {
		Page<AmountPromotion> pagedResult = PageHelper.startPage(pageNum, pageSize);
		amountPromotionMapper.listAmountPromotionStoreId(productStoreId, request);
		List<AmountPromotion> retList = pagedResult.getResult();
		if (CollectionUtils.isEmpty(retList)) {
			return pagedResult;
		}
		List<String> promotionIds = retList.stream().map(AmountPromotion::getId).collect(Collectors.toList());
		List<AmountPromotionConfigAmount> amounts = this.findConfigAmountByPromotionIds(promotionIds);
		List<AmountOrderInfo> orderInfos = amountPromotionMapper.findAmountOrderInfo(promotionIds);
		for (AmountPromotion promotion : retList) {
			if (promotion.getExpireDate().getTime() < new Date().getTime()) {
				promotion.setPromotionStatus("N");
			}
			for (AmountPromotionConfigAmount amount : amounts) {
				if (amount.getPromotionId().equals(promotion.getId())) {
					if (promotion.getPromotionAmounts() != null) {
						promotion.getPromotionAmounts().add(amount);
					} else {
						List<AmountPromotionConfigAmount> temps = Lists.newArrayList();
						temps.add(amount);
						promotion.setPromotionAmounts(temps);
					}
				}
			}
			//组合活动订单总量和总的满减数
			for (AmountOrderInfo orderInfo : orderInfos) {
				if (promotion.getId().equals(orderInfo.getPromotionId())) {
					promotion.setAmountTotal(orderInfo.getAmountTotal());
					promotion.setAvgAmount(orderInfo.getAvgAmount());
					promotion.setOrderTotal(orderInfo.getOrderTotal());
					promotion.setFirstOrderNum(orderInfo.getFirstOrderNum());
				}
			}
		}
		return pagedResult;
	}
	
	public int stopAmountPromotion(String promotionId, User user) {
		int ret = amountPromotionMapper.updateAmountPromotionStatus(promotionId, "N");
		if (ret > 0) {
			AmountPromotionUpdateRecord record = new AmountPromotionUpdateRecord();
			record.setId(new IncrementIdCreator().getNextIncrementId());
			record.setPromotionId(promotionId);
			record.setUserLoginId(user.getUserLoginId());
			record.setUserLoginName(user.getUserName());
			record.setCreatedStamp(new Date());
			record.setDescription("活动状态修改为 停止活动；");
			List<AmountPromotionUpdateRecord> records = Lists.newArrayList();
			records.add(record);
			updateRecordMapper.insertAmountPromotionRecords(records);
		}
		return ret;
	}
	
	private List<AmountPromotionConfig> listPromotionConfigs(List<String> promotionIds) {
		List<AmountPromotionConfig> configs = amountPromotionConfigMapper.listAmountPromotionConfigByPromotionIds(promotionIds);
		List<String> areaConfigIds = Lists.newArrayList();
		List<String> brandConfigIds = Lists.newArrayList();
		List<String> categoryConfigIds = Lists.newArrayList();
		if (CollectionUtils.isNotEmpty(configs)) {
			for (AmountPromotionConfig config : configs) {
				if (DiscountConfigValueEnum.AREA_LIMIT.getIndex().equals(config.getConfigType())
						&& DiscountConfigValueEnum.AREA_LIMIT_CUSTOM.getIndex().equals(config.getConfigValue())) {
					areaConfigIds.add(config.getId());
				} else if (DiscountConfigValueEnum.BRAND_LIMIT.getIndex().equals(config.getConfigType())) {
					brandConfigIds.add(config.getId());
				} else if (DiscountConfigValueEnum.CATEGORY_LIMIT.getIndex().equals(config.getConfigType())) {
					categoryConfigIds.add(config.getId());
				}
			}
		}
		if (CollectionUtils.isNotEmpty(areaConfigIds)) {
			List<AmountPromotionConfigArea> areas = amountPromotionConfigAreaMapper.listConfigAreaByConfigIds(areaConfigIds);
			for (AmountPromotionConfigArea area : areas) {
				for (AmountPromotionConfig config : configs) {
					if (config.getId().equals(area.getPromotionConfigId())) {
						if (config.getAreas() != null) {
							config.getAreas().add(area);
						} else {
							List<AmountPromotionConfigArea> temps = Lists.newArrayList();
							temps.add(area);
							config.setAreas(temps);
						}
					}
				}
			}
		}
		if (CollectionUtils.isNotEmpty(brandConfigIds)) {
			List<AmountPromotionConfigBrand> brands = amountPromotionConfigBrandMapper.listConfigBrandByConfigIds(brandConfigIds);
			for (AmountPromotionConfigBrand brand : brands) {
				for (AmountPromotionConfig config : configs) {
					if (config.getId().equals(brand.getPromotionConfigId())) {
						if (config.getBrands() != null) {
							config.getBrands().add(brand);
						} else {
							List<AmountPromotionConfigBrand> temps = Lists.newArrayList();
							temps.add(brand);
							config.setBrands(temps);
						}
					}
				}
			}
		}
		
		if (CollectionUtils.isNotEmpty(categoryConfigIds)) {
			List<AmountPromotionConfigCategory> categorys = amountPromotionConfigCategoryMapper.listConfigCategoryByConfigIds(categoryConfigIds);
			for (AmountPromotionConfigCategory category : categorys) {
				for (AmountPromotionConfig config : configs) {
					if (config.getId().equals(category.getPromotionConfigId())) {
						if (config.getCategorys() != null) {
							config.getCategorys().add(category);
						} else {
							List<AmountPromotionConfigCategory> temps = Lists.newArrayList();
							temps.add(category);
							config.setCategorys(temps);
						}
					}
				}
			}
		}
		return configs;
	}
	
	private void insertPromotionConfigs(AmountPromotion amountPromotion, IncrementIdCreator idCreator) {
		if (CollectionUtils.isNotEmpty(amountPromotion.getPromotionAmounts())) {
			for (AmountPromotionConfigAmount amount : amountPromotion.getPromotionAmounts()) {
				amount.setId(idCreator.getNextIncrementId());
				amount.setPromotionId(amountPromotion.getId());
			}
			amountPromotionConfigAmountMapper.insertConfigAmounts(amountPromotion.getPromotionAmounts());
		}
		if (CollectionUtils.isNotEmpty(amountPromotion.getPromotionConfigs())) {
			for (AmountPromotionConfig config : amountPromotion.getPromotionConfigs()) {
				config.setId(idCreator.getNextIncrementId());
				config.setPromotionId(amountPromotion.getId());
			}
			amountPromotionConfigMapper.insertAmountPromotionConfigs(amountPromotion.getPromotionConfigs());
			
			for (AmountPromotionConfig config : amountPromotion.getPromotionConfigs()) {
				if (CollectionUtils.isNotEmpty(config.getAreas())) {
					for (AmountPromotionConfigArea area : config.getAreas()) {
						area.setId(idCreator.getNextIncrementId());
						area.setPromotionConfigId(config.getId());
					}
					amountPromotionConfigAreaMapper.insertConfigAreas(config.getAreas());
				}
				if (CollectionUtils.isNotEmpty(config.getBrands())) {
					for (AmountPromotionConfigBrand brand : config.getBrands()) {
						brand.setId(idCreator.getNextIncrementId());
						brand.setPromotionConfigId(config.getId());
					}
					amountPromotionConfigBrandMapper.insertConfigBrands(config.getBrands());
				}
				if (CollectionUtils.isNotEmpty(config.getCategorys())) {
					for (AmountPromotionConfigCategory category : config.getCategorys()) {
						category.setId(idCreator.getNextIncrementId());
						category.setPromotionConfigId(config.getId());
					}
					amountPromotionConfigCategoryMapper.insertConfigCategorys(config.getCategorys());
				}
			}
		}
	}
	
	private AmountPromotionUpdateRecord createUpdateRecord(AmountPromotion oldPromotion, AmountPromotion newPromotion,
			IncrementIdCreator idCreator, User user, Date now) {
		AmountPromotionUpdateRecord record = new AmountPromotionUpdateRecord();
		record.setId(idCreator.getNextIncrementId());
		record.setPromotionId(oldPromotion.getId());
		record.setUserLoginId(user.getUserLoginId());
		record.setUserLoginName(user.getUserName());
		record.setCreatedStamp(now);
		StringBuffer description = new StringBuffer();
		SimpleDateFormat simpleformat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		if (!oldPromotion.getPromotionName().equals(newPromotion.getPromotionName())) {
			description.append(MessageFormat.format("活动名称 由 {0} 修改成 {1}；", oldPromotion.getPromotionName(), newPromotion.getPromotionName()));
		}
		if (!simpleformat.format(oldPromotion.getEffectDate()).equals(simpleformat.format(newPromotion.getEffectDate()))) {
			description.append(
					MessageFormat.format("活动开始时间 由 {0} 修改成 {1}；", simpleformat.format(oldPromotion.getEffectDate()),
							simpleformat.format(newPromotion.getEffectDate())));
		}
		if (!simpleformat.format(oldPromotion.getExpireDate()).equals(simpleformat.format(newPromotion.getExpireDate()))) {
			description.append(
					MessageFormat.format("活动结束时间 由 {0} 修改成 {1}；", simpleformat.format(oldPromotion.getExpireDate()),
							simpleformat.format(newPromotion.getExpireDate())));
		}
		if (!oldPromotion.getTargetPlatform().equals(newPromotion.getTargetPlatform())) {
			description.append(MessageFormat.format("活动平台 由 {0} 修改成 {1}；",
					DiscountConfigValueEnum.getName(oldPromotion.getTargetPlatform()),
					DiscountConfigValueEnum.getName(newPromotion.getTargetPlatform())));
		}
		if (!oldPromotion.getTargetCustomer().equals(newPromotion.getTargetCustomer())) {
			description.append(MessageFormat.format("活动对象 由 {0} 修改成 {1}；",
					DiscountConfigValueEnum.getName(oldPromotion.getTargetCustomer()),
					DiscountConfigValueEnum.getName(newPromotion.getTargetCustomer())));
		}
		if (!oldPromotion.getPromotionBudget().equals(newPromotion.getPromotionBudget())) {
			description.append(MessageFormat.format("活动预算 由 {0} 修改成 {1}；", oldPromotion.getPromotionBudget(),
					newPromotion.getPromotionBudget()));
		}
		if (!oldPromotion.getPromotionType().equals(newPromotion.getPromotionType())) {
			description.append(MessageFormat.format("满减类型 由 {0} 修改成 {1}；",
					DiscountConfigValueEnum.getName(oldPromotion.getPromotionType()),
					DiscountConfigValueEnum.getName(newPromotion.getPromotionType())));
			String oldCond = createPromotionTyeDescription(oldPromotion);
			String newCond = createPromotionTyeDescription(newPromotion);
			description.append(MessageFormat.format("满减条件 由 {0} 修改成 {1}", oldCond, newCond));
		} else if ((DiscountConfigValueEnum.FULLCUT_PER.getIndex().equals(oldPromotion.getPromotionType())
				|| DiscountConfigValueEnum.FULLCUT_NORMAL.getIndex().equals(oldPromotion.getPromotionType()))
				&& !isSameAmount(oldPromotion.getPromotionAmounts(), newPromotion.getPromotionAmounts())) {
			String oldCond = createPromotionTyeDescription(oldPromotion);
			String newCond = createPromotionTyeDescription(newPromotion);
			description.append(MessageFormat.format("满减条件 由 {0} 修改成 {1}", oldCond, newCond));
		}
		AmountPromotionConfig oldAreaConfig = null;
		AmountPromotionConfig oldBrandConfig = null;
		AmountPromotionConfig oldCategoryConfig = null;
		for (AmountPromotionConfig config : oldPromotion.getPromotionConfigs()) {
			if (DiscountConfigValueEnum.AREA_LIMIT.getIndex().equals(config.getConfigType())) {
				oldAreaConfig = config;
			} else if (DiscountConfigValueEnum.BRAND_LIMIT.getIndex().equals(config.getConfigType())) {
				oldBrandConfig = config;
			} else if (DiscountConfigValueEnum.CATEGORY_LIMIT.getIndex().equals(config.getConfigType())) {
				oldCategoryConfig = config;
			}
		}
		AmountPromotionConfig newAreaConfig = null;
		AmountPromotionConfig newBrandConfig = null;
		AmountPromotionConfig newCategoryConfig = null;
		for (AmountPromotionConfig config : newPromotion.getPromotionConfigs()) {
			if (DiscountConfigValueEnum.AREA_LIMIT.getIndex().equals(config.getConfigType())) {
				newAreaConfig = config;
			} else if (DiscountConfigValueEnum.BRAND_LIMIT.getIndex().equals(config.getConfigType())) {
				newBrandConfig = config;
			} else if (DiscountConfigValueEnum.CATEGORY_LIMIT.getIndex().equals(config.getConfigType())) {
				newCategoryConfig = config;
			}
		}
		if (newAreaConfig == null || newBrandConfig == null || newCategoryConfig == null || oldAreaConfig == null
				|| oldBrandConfig == null || oldCategoryConfig == null) {
			return null;
		}
		if (DiscountConfigValueEnum.AREA_LIMIT_DEFAULT.getIndex().equals(oldAreaConfig.getConfigValue())
				&& DiscountConfigValueEnum.AREA_LIMIT_CUSTOM.getIndex().equals(newAreaConfig.getConfigValue())) {
			String des = MessageFormat.format("活动城市 由 {0} 修改成 {1}；",
					DiscountConfigValueEnum.AREA_LIMIT_DEFAULT.getName(),
					DiscountConfigValueEnum.AREA_LIMIT_CUSTOM.getName());
			des += createAreaDiffDescription(Lists.newArrayList(), newAreaConfig.getAreas());
			description.append(des);
			
		} else if (DiscountConfigValueEnum.AREA_LIMIT_CUSTOM.getIndex().equals(oldAreaConfig.getConfigValue())
				&& DiscountConfigValueEnum.AREA_LIMIT_DEFAULT.getIndex().equals(newAreaConfig.getConfigValue())) {
			String des = MessageFormat.format("活动城市 由 {0} 修改成 {1}；",
					DiscountConfigValueEnum.AREA_LIMIT_CUSTOM.getName(),
					DiscountConfigValueEnum.AREA_LIMIT_DEFAULT.getName());
			description.append(des);
		} else if (DiscountConfigValueEnum.AREA_LIMIT_CUSTOM.getIndex().equals(newAreaConfig.getConfigValue())
				&& DiscountConfigValueEnum.AREA_LIMIT_CUSTOM.getIndex().equals(oldAreaConfig.getConfigValue())) {
			String areaChange = createAreaDiffDescription(oldAreaConfig.getAreas(), newAreaConfig.getAreas());
			if (StringUtils.isNotBlank(areaChange)) {
				description.append("修改活动城市：" + areaChange);
			}
		}
		
		String brandChange = createBrandDiffDescription(oldBrandConfig.getBrands(), newBrandConfig.getBrands());
		if (StringUtils.isNotBlank(brandChange)) {
			description.append("修改品牌限制：" + brandChange);
		}
		
		String categoryChange = createCategoryDiffDescription(oldCategoryConfig.getCategorys(), newCategoryConfig.getCategorys());
		if (StringUtils.isNotBlank(categoryChange)) {
			description.append("修改品类限制：" + categoryChange);
		}
		
		if (StringUtils.isNotBlank(description.toString())) {
			record.setDescription(description.toString());
			return record;
		} else {
			return null;
		}
	}
	
	private String createPromotionTyeDescription(AmountPromotion promotion) {
		String oldCond = "";
		String oldheadfix = "";
		if (DiscountConfigValueEnum.FULLCUT_PER.getIndex().equals(promotion.getPromotionType())) {
			oldheadfix = "每满";
		} else {
			oldheadfix = "满";
		}
		for (AmountPromotionConfigAmount configAmount : promotion.getPromotionAmounts()) {
			oldCond += MessageFormat.format("{0} {1} 立减 {2} ；", oldheadfix, configAmount.getRequireAmount(), configAmount.getOffAmount());
		}
		return oldCond;
	}
	
	private boolean isSameAmount(List<AmountPromotionConfigAmount> oldAmounts, List<AmountPromotionConfigAmount> newAmounts) {
		if (oldAmounts.size() != newAmounts.size()) {
			return false;
		} else if (oldAmounts.size() == 1 && (!oldAmounts.get(0).getOffAmount().equals(newAmounts.get(0).getOffAmount())
				|| !oldAmounts.get(0).getRequireAmount().equals(newAmounts.get(0).getRequireAmount()))) {
			return false;
		} else {
			List<String> oldList = Lists.newArrayList();
			List<String> newList = Lists.newArrayList();
			for (AmountPromotionConfigAmount configAmount : oldAmounts) {
				oldList.add(configAmount.getRequireAmount() + "_" + configAmount.getOffAmount());
			}
			for (AmountPromotionConfigAmount configAmount : newAmounts) {
				newList.add(configAmount.getRequireAmount() + "_" + configAmount.getOffAmount());
			}
			return (newList.size() == oldList.size()) && newList.containsAll(oldList);
		}
	}
	
	private String createAreaDiffDescription(List<AmountPromotionConfigArea> oldAreas, List<AmountPromotionConfigArea> newAreas) {
		String description = "";
		Map<String, String> geoMap = Maps.newHashMap();
		for (AmountPromotionConfigArea area : oldAreas) {
			geoMap.put(area.getGeoId(), area.getGeoName());
		}
		for (AmountPromotionConfigArea area : newAreas) {
			geoMap.put(area.getGeoId(), area.getGeoName());
		}
		
		List<String> removeArea = Lists.newArrayList();
		List<String> oldAreaIds = oldAreas.stream().map(AmountPromotionConfigArea::getGeoId).collect(Collectors.toList());
		oldAreaIds.removeAll(newAreas.stream().map(AmountPromotionConfigArea::getGeoId).collect(Collectors.toList()));
		if (oldAreaIds.size() > 0) {
			removeArea.addAll(oldAreaIds);
		}
		List<String> addArea = Lists.newArrayList();
		List<String> newAreaIds = newAreas.stream().map(AmountPromotionConfigArea::getGeoId).collect(Collectors.toList());
		newAreaIds.removeAll(oldAreas.stream().map(AmountPromotionConfigArea::getGeoId).collect(Collectors.toList()));
		if (newAreaIds.size() > 0) {
			addArea.addAll(newAreaIds);
		}
		
		if (addArea.size() != 0) {
			description += "新增城市：";
			for (String area : addArea) {
				if (geoMap.containsKey(area)) {
					description += geoMap.get(area) + "，";
				} else {
					description += area + "，";
				}
			}
			description  = description.substring(0, description.length() - 1);
			description += "；";
		}
		if (removeArea.size() != 0) {
			description += "删除城市：";
			for (String area : removeArea) {
				if (geoMap.containsKey(area)) {
					description += geoMap.get(area) + "，";
				} else {
					description += area + "，";
				}
			}
			description  = description.substring(0, description.length() - 1);
			description += "；";
		}
		
		return description;
	}
	
	private String createBrandDiffDescription(List<AmountPromotionConfigBrand> oldBrands, List<AmountPromotionConfigBrand> newBrands) {
		String description = "";
		Map<String, String> brandMap = Maps.newHashMap();
		for (AmountPromotionConfigBrand brand : oldBrands) {
			brandMap.put(brand.getBrandId(), brand.getBrandName());
		}
		for (AmountPromotionConfigBrand brand : newBrands) {
			brandMap.put(brand.getBrandId(), brand.getBrandName());
		}
		
		List<String> removeBrand = Lists.newArrayList();
		List<String> oldBrandIds = oldBrands.stream().map(AmountPromotionConfigBrand::getBrandId).collect(Collectors.toList());
		oldBrandIds.removeAll(newBrands.stream().map(AmountPromotionConfigBrand::getBrandId).collect(Collectors.toList()));
		if (oldBrandIds.size() > 0) {
			removeBrand.addAll(oldBrandIds);
		}
		List<String> addBrand = Lists.newArrayList();
		List<String> newBrandIds = newBrands.stream().map(AmountPromotionConfigBrand::getBrandId).collect(Collectors.toList());
		newBrandIds.removeAll(oldBrands.stream().map(AmountPromotionConfigBrand::getBrandId).collect(Collectors.toList()));
		if (newBrandIds.size() > 0) {
			addBrand.addAll(newBrandIds);
		}
		
		if (addBrand.size() != 0) {
			description += "新增品牌：";
			for (String brandId : addBrand) {
				if (brandMap.containsKey(brandId)) {
					description += brandMap.get(brandId) + "，";
				} else {
					description += brandId + "，";
				}
			}
			description  = description.substring(0, description.length() - 1);
			description += "；";
		}
		if (removeBrand.size() != 0) {
			description += "删除品牌：";
			for (String brandId : removeBrand) {
				if (brandMap.containsKey(brandId)) {
					description += brandMap.get(brandId) + "，";
				} else {
					description += brandId + "，";
				}
			}
			description  = description.substring(0, description.length() - 1);
			description += "；";
		}
		
		return description;
	}
	
	private String createCategoryDiffDescription(List<AmountPromotionConfigCategory> oldCategorys, List<AmountPromotionConfigCategory> newCategorys) {
		String description = "";
		Map<String, String> categoryMap = Maps.newHashMap();
		for (AmountPromotionConfigCategory category : oldCategorys) {
			categoryMap.put(category.getCategoryId(), category.getCategoryName());
		}
		for (AmountPromotionConfigCategory category : newCategorys) {
			categoryMap.put(category.getCategoryId(), category.getCategoryName());
		}
		
		List<String> removeCategory = Lists.newArrayList();
		List<String> oldCategoryIds = oldCategorys.stream().map(AmountPromotionConfigCategory::getCategoryId).collect(Collectors.toList());
		oldCategoryIds.removeAll(newCategorys.stream().map(AmountPromotionConfigCategory::getCategoryId).collect(Collectors.toList()));
		if (oldCategoryIds.size() > 0) {
			removeCategory.addAll(oldCategoryIds);
		}
		List<String> addCategory = Lists.newArrayList();
		List<String> newCategoryIds = newCategorys.stream().map(AmountPromotionConfigCategory::getCategoryId).collect(Collectors.toList());
		newCategoryIds.removeAll(oldCategorys.stream().map(AmountPromotionConfigCategory::getCategoryId).collect(Collectors.toList()));
		if (newCategoryIds.size() > 0) {
			addCategory.addAll(newCategoryIds);
		}
		
		if (addCategory.size() != 0) {
			description += "新增品类：";
			for (String categoryId : addCategory) {
				if (categoryMap.containsKey(categoryId)) {
					description += categoryMap.get(categoryId) + "，";
				} else {
					description += categoryId + "，";
				}
			}
			description  = description.substring(0, description.length() - 1);
			description += "；";
		}
		if (removeCategory.size() != 0) {
			description += "删除品类：";
			for (String categoryId : removeCategory) {
				if (categoryMap.containsKey(categoryId)) {
					description += categoryMap.get(categoryId) + "，";
				} else {
					description += categoryId + "，";
				}
			}
			description  = description.substring(0, description.length() - 1);
			description += "；";
		}
		
		return description;
	}
	
	List<AmountPromotionConfigAmount> findConfigAmountByPromotionIds(List<String> promotionIds) {
		if (CollectionUtils.isEmpty(promotionIds)) {
			return Lists.newArrayList();
		}
		List<AmountPromotionConfigAmount> amounts = amountPromotionConfigAmountMapper.findConfigAmountByPromotionIds(promotionIds);
		for (int i = 0; i < amounts.size(); i++) {
			float rati = Float.parseFloat(amounts.get(i).getOffAmount()) / Float.parseFloat(amounts.get(i).getRequireAmount());
			for (int j = i + 1; j < amounts.size(); j++) {
				float ratj = Float.parseFloat(amounts.get(j).getOffAmount()) / Float.parseFloat(amounts.get(j).getRequireAmount());
				if (rati < ratj || (Math.abs(ratj - rati) < 0.00001
						&& Float.parseFloat(amounts.get(i).getRequireAmount()) < Float.parseFloat(amounts.get(j).getRequireAmount()))) {
					AmountPromotionConfigAmount temp = amounts.get(i);
					amounts.set(i, amounts.get(j));
					amounts.set(j, temp);
				}
			}
		}
		return amounts;
	}
	
	/**
	 * validBrandAndCategory:(满减后台验证接口).<br/>  
	 * @param productStoreId
	 * @param startDate
	 * @param endDate
	 * @param brandIds
	 * @param categoryIds
	 * @return
	 * @author 徐彪
	 * @date 2018年3月24日 下午5:44:09
	 */
	public List<Map<String, String>> validBrandAndCategory(String productStoreId, Date startDate, Date endDate) {
		List<Map<String, String>> listDataBase = Lists.newArrayList();
		AmountPromotionRequest request = new AmountPromotionRequest();
		request.setStartDate(startDate);
		request.setEndDate(endDate);
		//根据店铺Id查找该时间段的活动
		List<AmountPromotion> listAmountPromotion = amountPromotionMapper.listValidAmountPromotionStoreId(productStoreId, request);
		List<String> listAmountPromotionId = listAmountPromotion.stream().map(AmountPromotion::getId).collect(Collectors.toList());
		if (CollectionUtils.isEmpty(listAmountPromotionId)) {
			return Lists.newArrayList();
		}
		//根据上述活动查找品牌
		List<AmountPromotionConfigBrand> listConfigBrand = amountPromotionConfigBrandMapper.listConfigBrandByPromotionIds(listAmountPromotionId);
		Map<String, List<AmountPromotionConfigBrand>> configBrandMap = Maps.newHashMap();
		for (AmountPromotionConfigBrand configBrand : listConfigBrand) {
			if (configBrandMap.containsKey(configBrand.getPromotionId())) {
				configBrandMap.get(configBrand.getPromotionId()).add(configBrand);
			} else {
				List<AmountPromotionConfigBrand> configBrands = Lists.newArrayList();
				configBrands.add(configBrand);
				configBrandMap.put(configBrand.getPromotionId(), configBrands);
			}
		}
		//根据上述活动查找品类
		List<AmountPromotionConfigCategory> listConfigCategory = amountPromotionConfigCategoryMapper.
				listConfigCategoryByPromotionIds(listAmountPromotionId);
		Map<String, List<AmountPromotionConfigCategory>> configCategoryMap = Maps.newHashMap();
		for (AmountPromotionConfigCategory configCategory : listConfigCategory) {
			if (configCategoryMap.containsKey(configCategory.getPromotionId())) {
				configCategoryMap.get(configCategory.getPromotionId()).add(configCategory);
			} else {
				List<AmountPromotionConfigCategory> configCategorys = Lists.newArrayList();
				configCategorys.add(configCategory);
				configCategoryMap.put(configCategory.getPromotionId(), configCategorys);
			}
		}
		//组装数据库数据
		for (Map.Entry<String, List<AmountPromotionConfigBrand>> configBrands : configBrandMap.entrySet()) {
			for (Map.Entry<String, List<AmountPromotionConfigCategory>> configCategorys : configCategoryMap.entrySet()) {
				if (configBrands.getKey().equals(configCategorys.getKey())) {
					List<String> listConfigBrandId = configBrands.getValue().
							stream().map(AmountPromotionConfigBrand::getBrandId).collect(Collectors.toList());
					List<String> listConfigCategoryId = configCategorys.getValue().
							stream().map(AmountPromotionConfigCategory::getCategoryId).collect(Collectors.toList());
					for (String configBrandId : listConfigBrandId) {
						for	(String configCategoryId : listConfigCategoryId) {
							Map<String, String> mapDataBase = Maps.newHashMap();
							if (!(mapDataBase.containsKey(configBrandId) && mapDataBase.get(configBrandId).equals(configCategoryId))) {
								mapDataBase.put(configBrandId, configCategoryId);
								listDataBase.add(mapDataBase);
							}
						}
					}
 				}
			}
		}
		return listDataBase;
	}
}
